/**
 *  This module contains utility functions to process the collections, set, subsets ...
 */

/**
 * Check if one element is in one set or not
 * @param x
 * @param X
 * @param fn
 * @returns {boolean}
 */
exports.set_in = function(x, X, fn) {
    if (!fn) {
        fn = function(a, b) {
            return a === b;
        };
    }
    for(var i = 0; i < X.length; i++) {
        if (fn(x, X[i])) {
            return true;
        }
    }
    return false;
};

/**
 * Create union of two sets
 * @param X
 * @param Y
 * @param fn
 * @returns {Array|string|Blob|*}
 */
exports.set_union = function(X, Y, fn) {
    if (!fn) {
        fn = function(a, b) {
            return a === b;
        };
    }
    var ret = Y.slice(0, Y.length);
    for(var i = 0; i < X.length; i++) {
        if (!this.set_in(X[i], Y, fn)) {
            ret.push(X[i]);
        }
    }
    return ret;
};

/**
 * Create intersection of two sets
 * @param X
 * @param Y
 * @param fn
 */
exports.set_intersection = function(X, Y, fn) {
    if (!fn) {
        fn = function(a, b) {
            return a === b;
        };
    }
    var ret = [];
    for(var i = 0; i < X.length; i++) {
        if (this.set_in(X[i], Y, fn)) {
            ret.push(X[i]);
        }
    }
    return ret;
};

/**
 * Create complement of set X with set Y
 * {1, 2, 3, 4} \ {1, 3} = {2, 4}
 * @param X
 * @param Y
 * @param fn
 */
exports.set_complement = function(X, Y, fn) {
    if (!fn) {
        fn = function(a, b) {
            return a === b;
        };
    }
    var ret = [];
    for(var i = 0; i < X.length; i++) {
        if (!this.set_in(X[i], Y, fn)) {
            ret.push(X[i]);
        }
    }
    return ret;
};
